#pragma once

#include <string>
#include <functional>
using namespace std;


namespace VIS
{
	class TileId
	{
		friend bool operator==(TileId const& lhs, TileId const& rhs);
		friend unsigned int qHash(TileId const&);

	public:
		TileId(string const& _mapThemeId, int _zoomLevel, int _tileX, int _tileY);
		TileId(unsigned int _mapThemeIdHash, int _zoomLevel, int _tileX, int _tileY);
		TileId(void);
		~TileId(void);

		int zoomLevel() const;
		int x() const;
		int y() const;
		unsigned int MapThemeIdHash() const;

		string toString() const;
		static TileId fromString(string const&);

	private:
		unsigned int m_mapThemeIdHash;
		int m_zoomLevel;
		int m_tileX;
		int m_tileY;
	};

	inline int TileId::x() const
	{
		return m_tileX;
	}

	inline int TileId::y() const
	{
		return m_tileY;
	}

	inline string TileId::toString() const
	{
		char buffer[255];
		sprintf_s(buffer, "%d:%d:%d:d", m_mapThemeIdHash, m_zoomLevel, m_tileX, m_tileY);
		return string(buffer);
	}

	inline bool operator==(TileId const& lhs, TileId const& rhs)
	{
		return lhs.m_zoomLevel == rhs.m_zoomLevel &&
			lhs.m_tileX == rhs.m_tileX &&
			lhs.m_tileY == rhs.m_tileY &&
			lhs.m_mapThemeIdHash == rhs.m_mapThemeIdHash;
	}

	inline unsigned int qHash(TileId const& tid)
	{
		std::hash<long> long_hash;
		const long tmp = ((long)(tid.m_zoomLevel) << 36) + 
			((long)(tid.m_tileX) << 18) +
			((long)(tid.m_tileY));

		return long_hash(tmp)^tid.m_mapThemeIdHash;
	}

}
